#include "victim_cache.h"

void victim_cache::compute(void)
{
  while (true) {

    wait();

    if (cs.read() == SC_LOGIC_1) { 

      _tag     = addr.read()(31, 9).to_uint();
      _index   = addr.read()( 8, 4).to_uint();
      _offset  = addr.read()( 3, 0).to_uint() * 8;
      _v_index = addr.read()( 5, 4).to_uint();

      /* READ */
      if (rw.read() == SC_LOGIC_0) {

        rdy.write(SC_LOGIC_0);
        wait(10, SC_NS); // reading one word
        rdy.write(SC_LOGIC_1);

        tout.write(_tab[_v_index]);

        dout0.write(_mem[_v_index]( 31,  0));
        dout1.write(_mem[_v_index]( 63, 32));
        dout2.write(_mem[_v_index]( 95, 64));
        dout3.write(_mem[_v_index](127, 96));

        /* hit */
        if (_tab[_v_index](29, 7) == _tag &&
            _tab[_v_index]( 6, 2) == _index &&
            _tab[_v_index][1] == SC_LOGIC_1)
          hit.write(SC_LOGIC_1);

        /* [compulsory] miss */
        else
          hit.write(SC_LOGIC_0);


      /* WRITE */
      } else if (rw.read() == SC_LOGIC_1) {

        rdy.write(SC_LOGIC_0);
        wait(40, SC_NS); // writing four words
        rdy.write(SC_LOGIC_1);

        _mem[_v_index].range( 31,  0) = din0.read();
        _mem[_v_index].range( 63, 32) = din1.read();
        _mem[_v_index].range( 95, 64) = din2.read();
        _mem[_v_index].range(127, 96) = din3.read();

        // write table [tag, index, valid]
        _tab[_v_index].range(29, 7) = _tag;
        _tab[_v_index].range( 6, 2) = _index;
        _tab[_v_index][1] = set_v.read();
        _tab[_v_index][0] = set_d.read();

      }

    }

  }
}
